#include "testApp.h"


//--------------------------------------------------------------
void testApp::setup(){
	
	ofxDaito::setup("oscSettings.xml");
	lastTagNumber = 0;
	ofSetFrameRate(90);
	
	bDrawPanel = false;
	currentFrame = 0;
	maxPanelNum = 5;
//	currentMode = MODE_WRITE;
	frameNum = NUM_FRAMES_WARP;
	
	for (int i=0; i<maxPanelNum; i++) {
		quadPointsPanel tmpPanel;
		tmpPanel.setup(i);
		panel.push_back(tmpPanel);		
	}
	
//	for(int i=0; i<panel.size();i++){
	panel[0].loadMovie("earth.mov");				
	panel[1].loadMovie("moon.mov");	
	panel[2].loadMovie("NIKA/_19sleeping/_n0046.mov");				
	panel[3].loadMovie("NIKA/_3jumping/_n0005.mov");				
	panel[4].loadMovie("TEST110423_05.mov");					
	

//	panel[3].loadMovie("NIKA/_3jumping/_n0005.mov");				
//	panel[4].loadMovie("TEST110423_05.mov");					
//	}
	
	currentPanel = 0;
	cout << "listening for osc messages on port " << PORT << "\n";
	receiver.setup( PORT );
	bAutoIncrementCurrentFrame = false;
	
	controlPanel.setup("util", 300, 300, 300, 300);
	controlPanel.addPanel("util", 1, false);
	controlPanel.addToggle("sendFrame", "SEND_CURRENTFRAME_", true);
	controlPanel.addSlider("lerp", "LERP_", 0.8, 0.0, 1.0, false);
	controlPanel.addSlider("calibFrame", "CALIBFRAME_", 1, 0, 5, true);
	
}

//--------------------------------------------------------------
void testApp::update(){
	
	if (ofGetFrameNum()%30 == 0) {
		ofxDaito::bang("alive", 1.0, 1.0);
	}	
	controlPanel.update();	
	bSendOSC = controlPanel.getValueB("SEND_CURRENTFRAME_");
	lerpVal = controlPanel.getValueF("LERP_");
	calibFrame = controlPanel.getValueI("CALIBFRAME_");
	receiveOSC();
	ofBackground(0,0,0);
	for (int i=0; i<panel.size(); i++) {	
		panel[i].update(currentFrame);
		panel[i].setLerp(lerpVal);
	}
	if (bAutoIncrementCurrentFrame) {
		incrementCurrentFrame();
	}
	
}

//--------------------------------------------------------------
void testApp::draw(){
	for (int i=0; i<panel.size(); i++) {	
		panel[i].draw();
	}
	
	ofSetColor(255, 255, 0);
	string str = "current frame = " +ofToString(currentFrame, 0) + "/" + ofToString(frameNum, 0) + "\n";
	for (int i=0; i<panel.size(); i++) {
		if (panel[i].bActive) {
			str += "panel[" + ofToString(i,0)+"]";
		}
	}
	str+= "\n";
	
	ofDrawBitmapString(str, 400, 10);
	if(bDrawPanel){
		controlPanel.draw();
	}
}


//--------------------------------------------------------------
void testApp::keyPressed  (int key){
	
	if (key == '1') {
		currentPanel = 0;
		panel[0].toggleActive();
		
	}
	else if (key == '2') {
		currentPanel = 1;
		panel[1].toggleActive();		
	}
	else if (key == '3') {
		currentPanel = 2;
		panel[2].toggleActive();		
	}
	else if (key == '4') {
		currentPanel = 3;
		panel[3].toggleActive();		
	}
	else if (key == '5') {
		currentPanel = 4;
		panel[4].toggleActive();		
	}
	else if (key == '6') {
		currentPanel = 5;
		panel[5].toggleActive();		
	}
	else if (key == '7') {
		currentPanel = 6;
		panel[6].toggleActive();		
	}
	else if (key == '8') {
		currentPanel = 7;
		panel[7].toggleActive();		
	}
	else if (key == '9') {
		currentPanel = 8;
		panel[8].toggleActive();		
	}

	
	for (int i=0; i<panel.size(); i++) {		
		panel[i].keyPressed(key);
	}
	
	if (key == ']') {
		incrementCurrentFrame();
	}
	if (key == '[') {
		decrementCurrentFrame();
	}
	if (key == 'f') {
		ofToggleFullscreen();
	}
	if (key == ' ') {
		currentFrame = 0;
		for (int i=0; i < panel.size(); i++) {
			panel[i].currentMode = MODE_READ;
		}
		bAutoIncrementCurrentFrame = !bAutoIncrementCurrentFrame;
	}
	
	if (key == 'i') {
		bDrawPanel = !bDrawPanel;
	}
	
	if (key == 'S') {
		//		saveXML();
		saveXML();
	}
	
	if (key == 'R') {
		//		saveXML();
		readXML();
	}
	
	if (key =='d') {
		debugy();
	}
	
}

//--------------------------------------------------------------
void testApp::mouseMoved(int x, int y ){
	for (int i=0; i<panel.size(); i++) {		
		panel[i].mouseMoved(x, y);
	}
}

//--------------------------------------------------------------
void testApp::mouseDragged(int x, int y, int button){
	controlPanel.mouseDragged(x, y, button);
	for (int i=0; i<panel.size(); i++) {		
		panel[i].mouseDragged(x, y, button);
	}
}

//--------------------------------------------------------------
void testApp::mousePressed(int x, int y, int button){
	controlPanel.mousePressed(x, y, button);
	for (int i=0; i<panel.size(); i++) {		
		panel[i].mousePressed(x, y, button);
	}
}

//--------------------------------------------------------------
void testApp::mouseReleased(int x, int y, int button){
	controlPanel.mouseReleased();
	for (int i=0; i<panel.size(); i++) {		
		panel[i].mouseReleased(x, y, button);
	}
}

//--------------------------------------------------------------
void testApp::windowResized(int w, int h){

}

void testApp::receiveOSC(){
	// check for waiting messages
	while( receiver.hasWaitingMessages() )
	{
		// get the next message
		ofxOscMessage m;
		receiver.getNextMessage( &m );
		
		// check for mouse moved message
		if ( m.getAddress() == "/frame" )
		{
//			for (int i=0; panel.size(); i++) {
//				panel[i].currentMode = MODE_READ;
//			}
//			for (int i=0; i<panel.size(); i++) {	
//				panel[i].update(currentFrame);
//			}
			
			// both the arguments are int32's
			currentFrame = m.getArgAsInt32( 0 ) + calibFrame;
			cout << "currentFrame" <<endl;
			cout << currentFrame <<endl;			
		}
	}
}

//void testApp::sendOSC(){
//	
//}
		

void testApp::incrementCurrentFrame(){
	currentFrame++;
	if (currentFrame>NUM_FRAMES_WARP - 1) {
		currentFrame = NUM_FRAMES_WARP - 1;
	}
	cout << "currentFrame" <<endl;
	cout << currentFrame <<endl;					
	if (bSendOSC) {
		ofxDaito::bang("/frame", currentFrame);
	}
	
}

void testApp::decrementCurrentFrame(){
	currentFrame--;
	if (currentFrame < 0) {
		currentFrame = 0;
	}	
	cout << "currentFrame" <<endl;
	cout << currentFrame <<endl;					
	if (bSendOSC) {
		ofxDaito::bang("/frame", currentFrame);
	}
	
}

void testApp::moveCurrentFrame(int _currentW){
	currentFrame = _currentW;
}

void testApp::debugy(){
	for (int i=0; i<panel.size(); i++) {	
		for (int j=0; j < panel[i].numFrames; j++) {
			if (panel[i].warpPointList[j].getLoaded()) {	
				cout << "i = " << i << " J = " << j << endl;
				cout << "panel[i].numFrames " << panel[i].numFrames << endl;
				
			}
		}
	}
}

void testApp::saveXML(){
//	XML.clear();
	lastTagNumber	= XML.addTag("STROKE");
	
	for (int i=0; i<panel.size(); i++) {	
		
		for (int j=0; j < panel[i].numFrames; j++) {
			if (panel[i].warpPointList[j].getLoaded()) {	
				
				if( XML.pushTag("STROKE", lastTagNumber) ){
//					XML.addTag(ofToString(i, 0));
//					if (XML.pushTag(ofToString(i, 0), 0)) {
					
						int tagNum = XML.addTag("PT");	
						
						XML.setValue("PT:FRAME", j, tagNum);
						XML.setValue("PT:LOADED", panel[i].warpPointList[j].bLoaded, tagNum);
						XML.setValue("PT:LTX", panel[i].warpPointList[j].pt[0].x, tagNum);
						XML.setValue("PT:LTY", panel[i].warpPointList[j].pt[0].y, tagNum);
						XML.setValue("PT:RTX", panel[i].warpPointList[j].pt[1].x, tagNum);
						XML.setValue("PT:RTY", panel[i].warpPointList[j].pt[1].y, tagNum);
						XML.setValue("PT:RBX", panel[i].warpPointList[j].pt[2].x, tagNum);
						XML.setValue("PT:RBY", panel[i].warpPointList[j].pt[2].y, tagNum);
						XML.setValue("PT:LBX", panel[i].warpPointList[j].pt[3].x, tagNum);
						XML.setValue("PT:LBY", panel[i].warpPointList[j].pt[3].y, tagNum);
						XML.setValue("PT:BCIRCLE", (int)panel[i].warpPointList[j].bCircle, tagNum);
						XML.setValue("PT:RADIUS", panel[i].warpPointList[j].radius, tagNum);				
						XML.popTag();		
					}
					XML.popTag();
			//	}
			}
		}	
	}
	XML.saveFile("mySettings.xml");
}

void testApp::readXML(){
	message = "loading mySettings.xml";
	
	//we load our settings file
	//if it doesn't exist we can still make one
	//by hitting the 's' key
	if( XML.loadFile("mySettings.xml") ){
		message = "mySettings.xml loaded!";
	}else{
		message = "unable to load mySettings.xml check data/ folder";
	}
	//we initalize some of our variables
	lastTagNumber	= 0;
	pointCount		= 0;
	lineCount		= 0;
	
	//-------
	//this is a more advanced use of ofXMLSettings
	//we are going to be reading multiple tags with the same name
	
	//lets see how many <STROKE> </STROKE> tags there are in the xml file
	int numDragTags = XML.getNumTags("STROKE:PT");
	
	//if there is at least one <STROKE> tag we can read the list of points
	//and then try and draw it as a line on the screen
	if(numDragTags > 0){
		
		//we push into the last STROKE tag
		//this temporarirly treats the tag as
		//the document root.
		XML.pushTag("STROKE", numDragTags-1);
		
		//we see how many points we have stored in <PT> tags
		int numPtTags = XML.getNumTags("PT");
		
		if(numPtTags > 0){
			
			
			
			int totalToRead = MIN(numPtTags, NUM_PTS);
			
			for(int i = 0; i < totalToRead; i++){
				
				int pframe = XML.getValue("PT:FRAME", -1, i);
//				panel[i]
				panel[0].warpPointList[pframe].bLoaded = XML.getValue("PT:LOADED", -1, i);
				panel[0].warpPointList[pframe].pt[0].x = XML.getValue("PT:LTX", -1.0, i);
				panel[0].warpPointList[pframe].pt[0].y = XML.getValue("PT:LTY", -1.0, i);
				panel[0].warpPointList[pframe].pt[1].x = XML.getValue("PT:RTX", -1.0, i);
				panel[0].warpPointList[pframe].pt[1].y = XML.getValue("PT:RTY", -1.0, i);
				panel[0].warpPointList[pframe].pt[2].x = XML.getValue("PT:RBX", -1.0, i);
				panel[0].warpPointList[pframe].pt[2].y = XML.getValue("PT:RBY", -1.0, i);
				panel[0].warpPointList[pframe].pt[3].x = XML.getValue("PT:LBX", -1.0, i);
				panel[0].warpPointList[pframe].pt[3].y = XML.getValue("PT:LBY", -1.0, i);
				panel[0].warpPointList[pframe].bCircle = XML.getValue("PT:BCIRCLE", -1, i);
				panel[0].warpPointList[pframe].radius = XML.getValue("PT:RADIUS", -1.0, i);				
				
				pointCount++;
			}
		}
		
		//this pops us out of the STROKE tag
		//sets the root back to the xml document
		XML.popTag();
	}
	
	//load a monospaced font
	//which we will use to show part of the xml structure
	
}